from __base__ import set_django_path

set_django_path()

import pika
import pickle
from lucommon.logger import lu_logger
from async_task.services import AsyncTask
from async_task.models import Task, TaskStatus
import conf
import traceback


def execute_task(task: Task):
    lu_logger.info("execute task {} {} {}".format(task.id, task.execute_func_name, task.name))

    async_task: AsyncTask = pickle.loads(task.execute_func)
    # task_params = pickle.loads(task.execute_params)

    try:
        code, task_result = async_task.task_impl(**async_task.task_kwargs)
        if code != 0:
            task.status = TaskStatus.FAIL
            task.result = task_result
        else:
            code, verify_result = async_task.verify_impl(**async_task.verify_kwargs)
            if code != 0:
                task.status = TaskStatus.FAIL
                task.result = verify_result
            else:
                task.status = TaskStatus.SUCCESS
                task.result = task_result
    except Exception as e:
        lu_logger.error(traceback.format_exc())
        task.status = TaskStatus.FAIL
        task.result = str(e.args)

    task.save()

    lu_logger.info("execute task {} {} {} finished".format(task.id, task.execute_func_name, task.name))


def callback(ch, method, properties, body):
    task = pickle.loads(body)
    execute_task(task)
    ch.basic_ack(delivery_tag=method.delivery_tag)


def worker():
    lu_logger.info("worker start")
    connection = pika.BlockingConnection(
        pika.ConnectionParameters(
            host=conf.RABBITMQ_HOST,
            port=conf.RABBITMQ_PORT,
            virtual_host=conf.RABBITMQ_VHOST,
            credentials=pika.PlainCredentials(conf.RABBITMQ_USER, conf.RABBITMQ_PASSWORD)
        ))
    connection.process_data_events(10)
    channel = connection.channel()
    channel.queue_declare(queue=conf.RABBITMQ_QUEUE)

    channel.basic_consume(queue="brood2", on_message_callback=callback, auto_ack=False)
    channel.start_consuming()


if __name__ == '__main__':
    worker()
